package org.javaforever.gatescore.generators;

import java.util.ArrayList;
import java.util.List;

import org.javaforever.gatescore.core.FrontDomain;
import org.javaforever.gatescore.core.FrontField;
import org.javaforever.gatescore.core.Statement;
import org.javaforever.gatescore.core.StatementList;
import org.javaforever.gatescore.core.Writeable;
import org.javaforever.gatescore.core.WriteableUtil;
import org.javaforever.gatescore.exception.ValidateException;
import org.javaforever.gatescore.utils.StringUtil;
import org.javaforever.gatescore.verb.SearchByFieldsByPage;

public class UtilMethodsGenerator {
	
	public static StatementList generateVueTreeExistsMethodStatementList(FrontDomain treeDomain,FrontField innerTreeParentId) {
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,1,"exists(rows, "+innerTreeParentId.getLowerFirstFieldName()+") {"));
		sList.add(new Statement(2000L,2,"for (var i = 0; i < rows.length; i++) {"));
		sList.add(new Statement(3000L,3,"if (rows[i]."+treeDomain.getDomainId().getLowerFirstFieldName()+" === "+innerTreeParentId.getLowerFirstFieldName()+") return true"));
		sList.add(new Statement(4000L,2,"}"));
		sList.add(new Statement(5000L,2,"return false"));
		sList.add(new Statement(6000L,1,"},"));
		return WriteableUtil.merge(sList);
	}

	public static StatementList generateVueTreeConvertMethodStatementList(FrontDomain treeDomain,FrontField innerTreeParentId) {
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"convert(rows) {"));
		sList.add(new Statement(2000L,1,"var nodes = []"));
		sList.add(new Statement(3000L,1,"// get the top level nodes"));
		sList.add(new Statement(4000L,1,"for (var i = 0; i < rows.length; i++) {"));
		sList.add(new Statement(5000L,2,"var row = rows[i]"));
		sList.add(new Statement(6000L,2,"if (!this.exists(rows, row."+innerTreeParentId.getLowerFirstFieldName()+")) {"));
		sList.add(new Statement(7000L,3,"nodes.push({"));
		sList.add(new Statement(8000L,4,"id: row."+treeDomain.getDomainId().getLowerFirstFieldName()+","));
		sList.add(new Statement(9000L,4,"label: row."+treeDomain.getDomainName().getLowerFirstFieldName()+""));
		sList.add(new Statement(10000L,3,"})"));
		sList.add(new Statement(11000L,2,"}"));
		sList.add(new Statement(12000L,1,"}"));
		sList.add(new Statement(14000L,1,"var toDo = []"));
		sList.add(new Statement(15000L,1,"for (var i = 0; i < nodes.length; i++) {"));
		sList.add(new Statement(16000L,2,"toDo.push(nodes[i])"));
		sList.add(new Statement(17000L,1,"}"));
		sList.add(new Statement(18000L,1,"while (toDo.length) {"));
		sList.add(new Statement(19000L,2,"var node = toDo.shift() // the parent node"));
		sList.add(new Statement(20000L,2,"// get the children nodes"));
		sList.add(new Statement(21000L,2,"for (var i = 0; i < rows.length; i++) {"));
		sList.add(new Statement(22000L,3,"var row = rows[i]"));
		sList.add(new Statement(23000L,3,"if (row."+innerTreeParentId.getLowerFirstFieldName()+" === node.id) {"));
		sList.add(new Statement(24000L,4,"var child = { id: row."+treeDomain.getDomainId().getLowerFirstFieldName()+", label: row."+treeDomain.getDomainName().getLowerFirstFieldName()+" }"));
		sList.add(new Statement(25000L,4,"if (node.children) {"));
		sList.add(new Statement(26000L,5,"node.children.push(child)"));
		sList.add(new Statement(27000L,4,"} else {"));
		sList.add(new Statement(28000L,5,"node.children = [child]"));
		sList.add(new Statement(29000L,4,"}"));
		sList.add(new Statement(30000L,4,"toDo.push(child)"));
		sList.add(new Statement(31000L,3,"}"));
		sList.add(new Statement(32000L,2,"}"));
		sList.add(new Statement(33000L,1,"}"));
		sList.add(new Statement(34000L,1,"return nodes"));
		sList.add(new Statement(35000L,0,"},"));
		return WriteableUtil.merge(sList);
	}
	
	public static StatementList generateVueTreeNodeClickMethodStatementList(FrontDomain childDomain,FrontField parentId) throws ValidateException{
		SearchByFieldsByPage search = new SearchByFieldsByPage(childDomain);
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"nodeClick(data, node) {"));
		sList.add(new Statement(2000L,1,"this.postForm."+parentId.getLowerFirstFieldName()+" = data.id"));
		sList.add(new Statement(3000L,1,"this."+StringUtil.lowerFirst(search.getVerbName())+"()"));
		sList.add(new Statement(4000L,1,"this.$refs.tree.setCheckedKeys([data.id])"));
		sList.add(new Statement(5000L,1,"this.childNodesChange(node)"));
		sList.add(new Statement(6000L,1,"this.parentNodesChange(node)"));
		sList.add(new Statement(7000L,1,"node.checked = true"));
		sList.add(new Statement(8000L,0,"},"));
		return WriteableUtil.merge(sList);
	}
	
	public static StatementList generateVueTreeChildNodesChangeMethodStatementList(FrontDomain treeDomain) throws ValidateException{
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"childNodesChange(node) {"));
		sList.add(new Statement(2000L,1,"let len = node.childNodes.length"));
		sList.add(new Statement(3000L,1,"for (let i = 0; i < len; i++) {"));
		sList.add(new Statement(4000L,2,"node.childNodes[i].checked = false"));
		sList.add(new Statement(5000L,2,"this.childNodesChange(node.childNodes[i])"));
		sList.add(new Statement(6000L,1,"}"));
		sList.add(new Statement(7000L,0,"},"));
		return WriteableUtil.merge(sList);
	}
	
	public static StatementList generateVueTreeParentNodesChangeMethodStatementList(FrontDomain treeDomain) throws ValidateException{
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"parentNodesChange(node) {"));
		sList.add(new Statement(2000L,1,"if (node.parent) {"));
		sList.add(new Statement(3000L,2,"for (let key in node) {"));
		sList.add(new Statement(4000L,3,"if (key === 'parent') {"));
		sList.add(new Statement(5000L,4,"node[key].checked = true"));
		sList.add(new Statement(6000L,4,"this.parentNodesChange(node[key])"));
		sList.add(new Statement(7000L,3,"}"));
		sList.add(new Statement(8000L,2,"}"));
		sList.add(new Statement(9000L,1,"}"));
		sList.add(new Statement(10000L,0,"},"));
		return WriteableUtil.merge(sList);
	}
	
	public static StatementList generateVueTreeDataMethodStatementList(FrontDomain treeDomain) throws ValidateException{
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,1,"treeData() {"));
		sList.add(new Statement(2000L,2,"return this.convert(this.active"+treeDomain.getCapFirstPlural()+")"));
		sList.add(new Statement(3000L,1,"},"));
		return WriteableUtil.merge(sList);
	}

}
